www.gusucode.com > Phased Array System Toolbox Add-On for Demorad 工具箱matlab源码程序 > Phased Array System Toolbox Add-On for Demorad/shared/radarboard/AbstractRadarBoard.m

    classdef (Abstract) AbstractRadarBoard < ...
    matlab.System & ...
    matlab.system.mixin.Propagates & ...
    matlab.system.mixin.CustomIcon & ...
    matlab.system.mixin.SampleTime & ...
    matlab.system.mixin.FiniteSource
  %This class is for internal use only.
  
  %AbstractRadarBoard Abstract class defining Radar hardware board interface
  
  % Copyright 2019 The MathWorks Inc.
  
  methods (Access = protected, Abstract)
    % Methods defined by the board
    rngIQ = acquireData(obj);
    poweredOn = powerOnBoard(obj)
    poweredOff = powerOffBoard(obj);
    success = configureBoard(obj);
  end
  
  properties (Nontunable)
    %SamplesPerFrame   Number of samples per frame
    %   Specify the number of fast-time samples returned by the radar board when
    %   calling the step method as powers of 2 less than or equal to
    %   256. The default value of this property is 256.
    SamplesPerFrame = 256
    %AcquisitionTime   Time collecting samples (s)
    %   Specify the length of time that the radar board will be operating for
    %   (in seconds). The default value of this property is 20 seconds.
    AcquisitionTime = 20
    %WindowMethod   Window Method
    %   Specify the type of window that is used to window the I/Q samples before
    %   being returned when calling the System objects step method. The
    %   supported windows are 'Hanning' | 'Hamming' | 'Chebyshev' |
    %   'Rectangular', where the default is 'Hanning'.
    WindowMethod = 'Hanning'
    %RampTime   Ramp up time (s)
    %   Specify the ramp up time of the FMCW chirp waveform (in seconds). This
    %   property must be less than the pulse repetition interval by 10 
    %   microseconds, and greater than 260 microseconds. The default
    %   value of this property is 280e-6, i.e., 280 microseconds. 
    %   
    %   NOTE: 
    %   The Demorad will only sample for 256 sample periods of the ADC, which 
    %   may be less than the entire waveform depending on the ramp time.
    RampTime = 264e-6
    %PRI   Pulse repetition interval (s)
    %   Specify the pulse repetition interval of the FMCW chirp waveform (in
    %   seconds). This property must be 10 microseconds greater than the ramp 
    %   up time of the chirp. The default value of this property is 300e-6, 
    %   i.e., 300 microseconds. 
    PRI = 300e-6
    %StartFrequency   Start frequency (Hz)
    %   Specify the start frequency of the FMCW chirp waveform (in Hz). This
    %   property must take a value between 24 GHz and 24.25 GHz. The
    %   default value of this property is 24e9, i.e., 24 GHz.
    StartFrequency = 24e9
    %StopFrequency   Stop frequency (Hz)
    %   Specify the stop frequency of the FMCW chirp waveform (in Hz). This
    %   property must take a value between 24 GHz and 24.25 GHz. The default
    %   value of this property is 24.25e9, i.e., 24.25 GHz.
    StopFrequency = 24.25e9
    %NumChirps   Number of chirps
    %   Specify the number of chirps to retrieve data from as a scalar. The
    %   number of chirps will be returned from the radar board, concatenated in
    %   the third dimension. This property may range from 1 - 128, where the 
    %   default value of this property is 1.
    NumChirps = 1
  end
  
  properties (Nontunable, Logical, Hidden)
    %Enabled   Board enabled
    %   Set this property to true to connect to and retrieve data from the radar
    %   board. Set this property to false to not connect to the board, and
    %   output only the chosen window from the step method.
    Enabled = true;
  end

  properties (Dependent)
    %Metadata    Waveform metadata
    %   This property is a struct that the user can access that contains all of
    %   the parameters that are required to define a waveform. For example, an
    %   FMCW waveform can be defined by its ramp time, pulse repetition
    %   interval, start frequency, and stop frequency.
    Metadata
    %CenterFrequency   Center frequency (Hz)
    %   The value of this property is the operating frequency of the Demorad (in
    %   Hz). The Demorad operates at 24.125e9 Hz, i.e., 24.125 GHz by default.
    CenterFrequency
  end
  
  properties (Abstract, Constant)
    NumChannels
    ReceiveElementSpacing
    TransmitElementSpacing
  end
  
  properties(Dependent, Abstract, SetAccess = private)
    TimeResolution
  end
  
  properties (Abstract, SetAccess = protected)
    SampleRate
  end
  
  properties (Abstract, Hidden, Constant)
    BoardName
  end
  
  properties (Access = protected)
    RadarBoard                                     % Radar board driver object
    Window                                         % FFT window
    CurrentTime = 0                                % Time since starting pings
  end
  
  properties (Hidden,Constant)
    WaveformType = 'FMCW'
    WindowMethodSet = matlab.system.StringSet( ...
    {'Hanning','Hamming','Chebyshev','Rectangular'})
    WaveformTypeSet = matlab.system.StringSet({'FMCW'})
  end
    
  properties (Hidden,Dependent)
    TRampUp % equivalent to RampTime
    FStart  % equivalent to StartFrequency
    FStop   % equivalent to StopFrequency
  end
  
  methods
    function set.SamplesPerFrame(obj,val)
      obj.privValidateRealFiniteScalars(val,'SamplesPerFrame',1,256);
      %make sure the value is a multiple of 2 -- driver issue
      if ~eq(log2(val),floor(log2(val)))
        error('AbstractRadarBoard:ExpectedPowerOfTwo', ...
          ['The number of samples must be a power of 2 less than or ' ...
          'equal to 256.']);
      end
      obj.SamplesPerFrame = val;
    end
    
    function set.AcquisitionTime(obj,val)
      obj.privValidateRealFiniteScalars(val,'AcquisitionTime');
      obj.AcquisitionTime = val;
    end
    
    function set.PRI(obj,val)
      obj.privValidateRealFiniteScalars(val,'PRI');
      obj.PRI = val;
    end
    
    function set.RampTime(obj,val)
      obj.privValidateRealFiniteScalars(val,'RampTime',260e-6,inf);
      obj.RampTime = val;
    end
    
    function set.StartFrequency(obj,val)
      obj.privValidateRealFiniteScalars(val,'StartFrequency',24e9,24.25e9);
      obj.StartFrequency = val;
    end
    
    function set.StopFrequency(obj,val)
      obj.privValidateRealFiniteScalars(val,'StopFrequency',24e9,24.25e9);
      obj.StopFrequency = val;
    end
    
    function set.NumChirps(obj,val)
      obj.privValidateRealFiniteScalars(val,'NumChirps',1,128);
      obj.NumChirps = val;
    end
    
    function wfMetadata = get.Metadata(obj)
%       wfMetadata.RampTime = obj.RampTime;
      wfMetadata.PRI = obj.PRI;
%       wfMetadata.StartFrequency = obj.StartFrequency;
%       wfMetadata.StopFrequency = obj.StopFrequency;
      wfMetadata.SweepSlope = (obj.StopFrequency-obj.StartFrequency)/obj.RampTime;
      
      % for compatibility
      wfMetadata.FStart = obj.StartFrequency;
      wfMetadata.FStop = obj.StopFrequency;
      wfMetadata.TRampUp = obj.RampTime;
    end
    
    function centerFrequency = get.CenterFrequency(obj)
      centerFrequency = (obj.StartFrequency + obj.StopFrequency)/2;
    end
    
    function val = get.TRampUp(obj)
      val = obj.RampTime;
    end
    
    function set.TRampUp(obj,val)
      obj.RampTime = val;
    end
    
    function val = get.FStart(obj)
      val = obj.StartFrequency;
    end
    
    function set.FStart(obj,val)
      obj.StartFrequency = val;
    end
    
    function val = get.FStop(obj)
      val = obj.StopFrequency;
    end
    
    function set.FStop(obj,val)
      obj.StopFrequency = val;
    end
    
    function set.Metadata(~,~)
      % Empty since Metadata is dependent
      error('Metadata is a read-only property');
    end
    
    function set.CenterFrequency(~,~)
      % Empty since CenterFrequency is dependent
      error('Metadata is a read-only property');
    end
  end
  
  methods (Access = protected)
    % System object-required functions
    function obj = AbstractRadarBoard
      % Empty Constructor
    end
    
    function setupImpl(obj)
      % Create the window for data collection
      win = privSelectWindow(obj);
      obj.Window = win*ones(1,obj.NumChannels); 
            
      if ~obj.Enabled
        % If the board is not enabled, do not connect.
        warning([obj.BoardName ' is not enabled. Will not receive data.' newline ...
          'To enable ' obj.BoardName ', set the ''Enabled'' property to true.']);
        return;
      end
      
      % Power on board
      on = obj.powerOnBoard();
      if ~on
        error('AbstractRadarBoard:CannotPowerOn', ['Unable to power on ' ...
          obj.BoardName '. Please disconnect and reconnect USB interface.']);
      end
      
      % Send configuration to board
      success = obj.configureBoard();
      if ~success
        error('AbstractRadarBoard:CannotConfigure',...
          ['Was not able to configure ' obj.BoardName ...
          ' to desired specifications.' ...
          '. Please disconnect and reconnect USB interface.']);
      end
    end
    
    function rngIQ = stepImpl(obj)
      if ~obj.Enabled
        % Output one-frames if the board is not enabled
        rngIQ = ones(obj.SamplesPerFrame,obj.NumChannels,obj.NumChirps);
      else
        rngIQ = obj.acquireData();
        
        if obj.SamplesPerFrame ~= 256
          % Added becuase while the drivers do not respect the number of desired
          % samples given to them.
          spacing = floor(256/obj.SamplesPerFrame);
          rngIQ = rngIQ(1:spacing:256,:,:);
        end
      end
      rngIQ = rngIQ.*obj.Window;
      
      % increment current time based on demorad clock
      obj.CurrentTime = obj.CurrentTime + obj.TimeResolution;
    end
    
    function releaseImpl(obj)
      if obj.Enabled && ~obj.powerOffBoard()
        error('AbstractRadarBoard:CannotPowerOff', ...
          ['Failed to power off ' obj.BoardName '. ' ...
          'Unplug power from' obj.BoardName ...
          ' and delete object before retrying.']);
      end
    end
    
    function resetImpl(obj)
      obj.CurrentTime = 0;
    end
    
    % Simulink extension-required functions
    
    function flag = isDoneImpl(obj)
      flag = obj.CurrentTime >= obj.AcquisitionTime;
    end
    
    function out = getOutputSizeImpl(obj)
      out = [obj.SamplesPerFrame obj.NumChannels obj.NumChirps];
    end
    
    function out = getOutputDataTypeImpl(~)
      % Return data type for each output port
      out = 'double';
    end
    
    function out = isOutputComplexImpl(~)
      % Return true for each output port with complex data
      out = true;
    end
    
    function out = isOutputFixedSizeImpl(~)
      % Return true for each output port with fixed size
      out = true;
    end
    
    function name = getOutputNamesImpl(~)
      name = 'I/Q';
    end
     
    function icon = getIconImpl(obj)
      icon = obj.BoardName;
    end
    
    function sts = getSampleTimeImpl(obj)
      sts = createSampleTime(obj,'Type','Discrete', ...
        'SampleTime',obj.TimeResolution, ...
        'OffsetTime',0);
    end
    
    function flag = isInactivePropertyImpl(obj,prop)
      flag = false;
      if ~strcmp(obj.WaveformType,'FMCW')
        % Only FMCW is supported.
        flag = strcmp(prop,'RampTime') || ... 
               strcmp(prop,'PRI') || ...
               strcmp(prop,'StartFrequency') || ...
               strcmp(prop,'StopFrequency');
      end
    end
  end
  
  methods (Static, Access = protected)
    function groups = getPropertyGroupsImpl
      % Only FMCW is supported.
      mainGroup = matlab.system.display.Section(...
        'Title','Hardware Parameters','PropertyList',{'TransmitPower', ...
        'AcquisitionTime','NumChirps'});
      radarParams = matlab.system.display.Section(...
        'Title','','PropertyList', ...
        {'WindowMethod','SamplesPerFrame'});
      waveformParams = matlab.system.display.Section(...
        'Title','Waveform Parameters','PropertyList',{ ...
        'StartFrequency','StopFrequency','RampTime','PRI'});
      groups = [mainGroup radarParams waveformParams];
    end
    
     function simMode = getSimulateUsingImpl
       % 3P drivers require interpreted execution
       simMode = "Interpreted execution";
    end
  end
  
  methods (Access = private)
    function win = privSelectWindow(obj)
      switch(obj.WindowMethod)
        case 'Hanning'
          win = hanning(obj.SamplesPerFrame);
        case 'Hamming'
          win = hamming(obj.SamplesPerFrame);
        case 'Chebyshev'
          win = chebwin(obj.SamplesPerFrame);
        case 'Rectangular'
          win = rectwin(obj.SamplesPerFrame);
        otherwise
          error('Unknown window function specified.');
      end
      win = win./sum(win); % scale window
    end
   
    function privValidateRealFiniteScalars(~,val,propname,varargin)
      % All properties should be real-finite scalars within a specified range
      if ~isempty(varargin)
        upperbound = varargin{2};
        lowerbound = varargin{1};
        attrs = {'real','finite','nonnan','nonempty','scalar','positive', ...
        '<=',upperbound,'>=',lowerbound};
      else
        attrs = {'real','finite','nonnan','nonempty','scalar','positive'};
      end
      
      validateattributes(val, {'double','single'}, attrs, 'RadarBoard',propname);
    end
  end
end